package com.tbsoft.ehr.service.common;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.opensymphony.xwork2.ActionContext;
import com.tbsoft.ehr.dao.common.WorkdayDao;
import com.tbsoft.ehr.model.WorkDay;
import com.tbsoft.ehr.model.WorkDaySet;

public class WorkdayServiceImpl implements WorkdayService {
	private Log log = LogFactory.getLog(getClass());
	private WorkdayDao workdayDao;

	public synchronized void setWorkdayDao(WorkdayDao workdayDao) {
		this.workdayDao = workdayDao;
	}

	@Override
	public List<Date> getWorkDays(Date start, Date end, String sex) {
		List<Date> dateList = new ArrayList<Date>();
		try {
			DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
			List<WorkDay> tlist = workdayDao.getDays(df.format(start), df.format(end));
			List<WorkDay> clist = this.getWorkDaysByCalendar(start, end);

			clist = this.mergeWorkDay(tlist, clist);

			for (WorkDay wd : clist) {
				if (!(wd.getDateType().equals("P") && ("A".equals(wd.getSexType()) || wd.getSexType().equals(sex)))) {
					dateList.add(df.parse(wd.getDate()));
				}
			}
		} catch (Exception e) {
			log.error("parse exception:", e);
		}

		return dateList;
	}

	private List<WorkDay> mergeWorkDay(List<WorkDay> tlist, List<WorkDay> clist) {
		for (WorkDay twd : tlist) {
			for (WorkDay cwd : clist) {
				if (twd.getDate().equals(cwd.getDate())) {
					cwd.setDateType(twd.getDateType());
					cwd.setSexType(twd.getSexType());
					cwd.setHolidayType(twd.getHolidayType());
					break;
				}
			}
		}
		return clist;

	}

	private List<WorkDay> getWorkDaysByCalendar(Date start, Date end) {
		DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
		List<WorkDay> list = new ArrayList<WorkDay>();
		Calendar calStart = Calendar.getInstance();
		calStart.setTime(start);
		Calendar calEnd = Calendar.getInstance();
		calEnd.setTime(end);
		Calendar calStep = Calendar.getInstance();

		for (calStep.setTime(start); calStep.compareTo(calEnd) <= 0; calStep.add(Calendar.DATE, 1)) {
			int weekday = calStep.get(Calendar.DAY_OF_WEEK);
			WorkDay wd = new WorkDay();
			wd.setDate(df.format(calStep.getTime()));
			wd.setDateType(weekday >= Calendar.MONDAY && weekday <= Calendar.FRIDAY ? "W" : "P");
			wd.setSexType("A");
			list.add(wd);
		}
		return list;
	}

	@Override
	public boolean isWorkDay(Date date, String sex) {
		DateFormat df = new SimpleDateFormat("yyyy-MM-dd");
		WorkDay wd = workdayDao.getWorkDayByDate(df.format(date));
		if (wd != null && ("A".equals(wd.getSexType()) || wd.getSexType().equals(sex))) {
			return wd.getDateType().equals("W");
		} else {
			return isWorkDayByCalendar(date);
		}
	}

	/**
	 * @desc 根据日期判断是否是工作日
	 * @param date
	 * @return
	 */
	private boolean isWorkDayByCalendar(Date date) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		int weekday = cal.get(Calendar.DAY_OF_WEEK);
		return weekday >= Calendar.MONDAY && weekday <= Calendar.FRIDAY ? true : false;
	}

	@SuppressWarnings("unchecked")
	@Override
	public List<WorkDaySet> getWorkDaySetBy(String year) {
		List<WorkDaySet> wdsList = new ArrayList<WorkDaySet>();
		List<WorkDay> list = workdayDao.getDaysByYear(year);
		Map<String, Map> holidayMap = (Map<String, Map>) (((Map) ActionContext.getContext().getApplication()
				.get("PUBFIELD_MAP")).get("HOLIDY_TYPE"));
		for (Iterator<?> itr = holidayMap.keySet().iterator(); itr.hasNext();) {
			String key = (String) itr.next();
			WorkDaySet wds = findByWorkDayList(list, key);
			if(wds == null){
				wds = new WorkDaySet();
				wds.setHolidayType(key);
				if (key.equals("8WD")) {
					wds.setSex("F");
					wds.setHolidays(year + "-03-08");
				}
			}
			wdsList.add(wds);
		}
		return wdsList;
	}
	private WorkDaySet findByWorkDayList(List<WorkDay> list,String holidayType){
		if(list.size() == 0){
			return null;
		}
		WorkDaySet wds=null;
		String holidays="";
		String workdays="";
		String sex = "";
		for(WorkDay wd : list){
			if(wd.getHolidayType().equals(holidayType)){
				if(wd.getDateType().equals("P")){ 
					holidays += ";"+wd.getDate();
				}else{
					workdays += ";"+wd.getDate();
				}
				sex = wd.getSexType();
			}

		}
		if(!holidays.isEmpty()){
			wds = new WorkDaySet();
			wds.setSex(sex);
			wds.setHolidayType(holidayType);
			if(holidays.length()>1){
				wds.setHolidays(holidays.substring(1));
			}
			if(workdays.length()>1){
				wds.setWorkdays(workdays.substring(1));
			}
		}
		return wds;
	}
	@Override
	public void saveWorkDays(String year, List<WorkDaySet> list) {
		workdayDao.deleteDaysByYear(year);
		List<WorkDay> wdList = new ArrayList<WorkDay>();
		for (WorkDaySet wds : list) {
			String holidays = wds.getHolidays();
			if (holidays != null && !holidays.isEmpty()) {
				String[] holiArrays = holidays.split("[;|\\s|,]");
				for (String hld : holiArrays) {
					WorkDay wd = new WorkDay(hld, wds.getHolidayType(), "P", wds.getSex());
					wdList.add(wd);
				}
			}
			String workdays = wds.getWorkdays();
			if (workdays != null && !workdays.isEmpty()) {
				String[] workArrays = workdays.split("[;|\\s|,]");
				for (String wkd : workArrays) {
					WorkDay wd = new WorkDay(wkd, wds.getHolidayType(), "W", wds.getSex());
					wdList.add(wd);
				}
			}
		}
		workdayDao.saveList(wdList);
	}

}
